using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using GameForKids;

namespace GameFramework
{
    public class ScrollView : DrawableGameComponent
    {
        /*display item number*/
        FrameModule _normalFrame;
        FrameModule _selectedFrame;
        bool _enableDisplayItemNumber;
        List<Vector2> _itemsNumberPosition;

        private int _currentItemIndex;
        private bool _isOnDrag;
        List<ViewItem> _items;

        public List<ViewItem> Items
        {
            get
            {
                return _items;
            }
            set
            {
                _items = value;
            }
        }

        public event EventHandler ItemSelected;

        public ScrollView(Game game)  : base(game)
        {
            _items = new List<ViewItem>();
            _currentItemIndex = 0;            
            _isOnDrag = false;
        }

        public void AddItem(ViewItem item)
        {
            if (_items == null)
                _items = new List<ViewItem>();
            else
            {
                item.Index = _items.Count;
                item.Selected += item_Selected;
                _items.Add(item);
            }
        }

        void item_Selected(object sender, EventArgs e)
        {
            if (ItemSelected != null)
                ItemSelected(sender, e);
        }

        public void SetUpItemsPosition(float dx)
        {
            float nextDX = 0;
            
            Point center = Game.GraphicsDevice.Viewport.Bounds.Center;
            center.Y += 30;

            foreach (ViewItem item in _items)
            {
                Vector2 position = new Vector2(center.X + nextDX, center.Y);
                item.Position = position;
                item.CenterItemPosition = new Vector2(center.X,center.Y);
                item.ItemDistance = dx;
                nextDX += dx;
            }
        }

       

        public void HandleInput(GameTime gameTime, InputState input)
        {      
            /*Handle input for all items*/
            foreach (GestureSample gesture in input.Gestures)
            {
                switch (gesture.GestureType)
                {                   
                    case GestureType.HorizontalDrag:
                        _isOnDrag = true;
                        float dx = gesture.Delta.X;
                        if ((dx < 0 && CanMoveLeft()) || (dx > 0 && CanMoveRight()))
                        {
                            foreach (ViewItem item in _items)
                            {
                                item.Move(dx, 0);
                                MainMenuScreen.moveBackground = -(int)dx/2;
                            }
                        }
                        UpdateCurrentIndex();
                        break;

                    case GestureType.Flick:
                        if (gesture.Delta.X > 0 && gesture.Delta.Y == 0)//flick right
                        {
                            if (_currentItemIndex > 0)
                                _currentItemIndex -= 1;
                        }
                        else if (gesture.Delta.X < 0 && gesture.Delta.Y == 0)//flick left
                        {
                            if (_currentItemIndex < _items.Count - 1)
                                _currentItemIndex += 1;
                        }
                        _isOnDrag = false;
                        break;
                    case GestureType.DragComplete:
                        _isOnDrag = false;
                        break;
                }
            }
            foreach (ViewItem item in _items)
            {
                item.HandleInput(gameTime,input);
            }
        }

        public void UpdateCurrentIndex()
        {
            _currentItemIndex = -1;
            float dMaxCenter = 0;
            foreach (ViewItem item in _items)
            {
                Rectangle viewPort = Game.GraphicsDevice.Viewport.Bounds;
                Rectangle interSectRect = Rectangle.Intersect(viewPort, item.GetBound());
                if (interSectRect.Width > 0 || interSectRect.Height > 0)
                {
                    if (item.GetComputeCenterData() > dMaxCenter)
                    {
                        dMaxCenter = item.GetComputeCenterData();
                        _currentItemIndex = item.Index;
                     
                    }
                }
            }            
        }

        public override void Update(GameTime gameTime)
        {
            /*Update all Items*/
            foreach (ViewItem item in _items)
            {
                Rectangle viewPort = Game.GraphicsDevice.Viewport.Bounds;
                Rectangle interSectRect = Rectangle.Intersect(viewPort, item.GetBound());
                if(interSectRect.Width > 0 || interSectRect.Height > 0)
                {
                    item.Update(gameTime);
                }
            }

            if (!_isOnDrag && _items[_currentItemIndex].GetComputeCenterData() != 1)//move the center item to right place
            {
                float viewCenterX = Game.GraphicsDevice.Viewport.Bounds.Center.X;
                float itemCenterX = _items[_currentItemIndex].Position.X;

                float dx = viewCenterX - itemCenterX;

                if (Math.Abs(dx) > 2)
                {
                    dx = dx * 0.1f + Math.Sign(dx)*1;
                    foreach (ViewItem item in _items)
                    {
                        item.Move(dx, 0);
                    }
                }
                else if(dx != 0)
                {
                    foreach (ViewItem item in _items)
                    {
                        item.Move(dx, 0);
                        MainMenuScreen.moveBackground = 0;
                        
                    }                    
                }               
            }

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
  
            /*Draw all Items*/
            foreach (ViewItem item in _items)
            {
                Rectangle viewPort = Game.GraphicsDevice.Viewport.Bounds;
                Rectangle interSectRect = Rectangle.Intersect(viewPort, item.GetBound());
                if (interSectRect.Width > 0 || interSectRect.Height > 0)
                {
                    item.Draw(gameTime);
                }
            }

            if (_enableDisplayItemNumber)
            {
                for (int i = 0; i < _items.Count; i++)
                {
                    if (_currentItemIndex == i)//selected
                    {
                        _selectedFrame.Draw(_itemsNumberPosition[i]);
                    }
                    else
                    {
                        _normalFrame.Draw(_itemsNumberPosition[i]);
                    }
                }
            }

            base.Draw(gameTime);
        }       

        private bool CanMoveRight()
        {
            if (_items[0].Position.X <= Game.GraphicsDevice.Viewport.Width)
                return true;
            return false;
        }

        private bool CanMoveLeft()
        {
            if (_items[_items.Count - 1].Position.X >= 0)
                return true;
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="position"></param>
        /// <param name="itemDistance"></param>
        /// <param name="normalFrame"></param>
        /// <param name="selectedFrame"></param>
        public void EnableDisplayItemNumber(Vector2 position, float itemDistance, FrameModule normalFrame, FrameModule selectedFrame)
        {
            _enableDisplayItemNumber = true;
            _normalFrame = normalFrame;
            _selectedFrame = selectedFrame;

            _itemsNumberPosition = new List<Vector2>();

            Vector2 startPosition = new Vector2(position.X,position.Y);

            if (_items.Count % 2 == 0)
            {
                startPosition.X -= ((int)((_items.Count -1) / 2)) * itemDistance + itemDistance/2;
            }
            else
            {
                startPosition.X -= ((int)(_items.Count / 2)) * itemDistance;
            }

            for (int i = 0; i < _items.Count; i++)
            {
                Vector2 iPos = new Vector2(startPosition.X, startPosition.Y);
                _itemsNumberPosition.Add(iPos);
                startPosition.X += itemDistance;
            }

        }
    }
}
